package com.hww.gannan.common;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteTable;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.MediaType;

import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

public abstract class EasyExcelTemplate<T, D> {

    //数据逻辑
    public abstract List<D> processData(List<T> t);

    /**
     * @param list 数据库
     * @return 最终需要导入的数据
     */
    public abstract List<List<D>> dataList(List<T> list);

    /**
     * 组装头部
     *
     * @param head
     * @return
     */
    private List<List<String>> headList(String[] head) {
        if (head == null || head.length == 0) {
            return null;
        }
        List<List<String>> headList = new ArrayList<>();
        for (int i = 0; i < head.length; i++) {
            List<String> headItem = new ArrayList<>();
            headItem.add(head[i]);
            headList.add(headItem);
        }
        return headList;
    }


    /**
     * @param response    HttpServletResponse
     * @param d           数据list
     * @param objectClass 对象class
     * @param fileName    文件名
     * @throws IOException
     */
    public void exportData(HttpServletResponse response, List<D> d, Class<D> objectClass, String fileName) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        //   Student.class 是按导出类  data()应为数据库查询数据，这里只是模拟
        EasyExcel.write(response.getOutputStream(), objectClass).sheet("模板").doWrite(d);
    }

    /**
     * 有对象导出
     */
    public void run(List<T> listData, HttpServletResponse response, Class<D> objectClass, String fileName) throws IOException {
        List<D> processData = processData(listData);
        exportData(response, processData, objectClass, fileName);
    }


    /**
     * 无对象导出
     *
     * @param listData 数据
     * @param fileName 文件名
     */
    public void run(List<T> listData, String fileName, String[] head, HttpServletResponse response) throws IOException {
        List<List<String>> headList = headList(head);
        List<List<D>> lists = dataList(listData);
        downloadFailedUsingJson(response, headList, lists, fileName);
    }

    public void multipleExport(String fileName, HttpServletResponse response) throws IOException {

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setCharacterEncoding("utf-8");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("access-Control-Allow-Origin", "*");
        response.setHeader("content-disposition",
                "attachment;filename*=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));

        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        //  response.setHeader("Content-disposition", "attachment;filename*=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");

    }

    public ExcelWriter addAll(List<T> listData, String[] head, ExcelWriter excelWriter, String SheetName, Integer num) {

        List<List<String>> headList = headList(head);
        List<List<D>> lists = dataList(listData);

        //将多个sheet的数据和表头添加到ExcelWriter中
        WriteTable writeTable = new WriteTable();
        writeTable.setTableNo(num);
        writeTable.setHead(headList);
        synchronized (excelWriter) {
            return  excelWriter.write(lists, EasyExcel.writerSheet(num, SheetName).build(), writeTable);
        }


    }

    /**
     * @param response
     * @param headList 显示的字段名,excel的列头
     * @param lists    数据内容
     * @param fileName 导出的文件名
     * @throws IOException
     */
    private void downloadFailedUsingJson(HttpServletResponse response,
                                         List<List<String>> headList, List<List<D>> lists, String fileName) throws IOException {
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setCharacterEncoding("utf-8");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("access-Control-Allow-Origin", "*");
        /*response.setHeader("content-disposition",
                "attachment;filename*=" + URLEncoder.encode(filename + ".xls", "UTF-8"));*/

        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        response.setHeader("Content-disposition", "attachment;filename*=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
        // 这里需要设置不关闭流
        EasyExcel.write(response.getOutputStream()).head(headList)
                .autoCloseStream(Boolean.FALSE).sheet(fileName)
                .doWrite(lists);
    }
}
